Post

Replies

Boosts

Views

Activity

NSMetadataQueryDidFinishGathering not being called enough
I have an app where each item in an NSTableView contains an NSMetadataQuery, to listen for updates to image files that contain the keyword associated with the item. If I write the keywords to, RAW files, everything works as expected and the number label in the row gets updated correctly. However, if I write the keywords to XMP sidecar files, the NSMetadataQueryDidFinishGathering callback isn't called enough times and the count of files affected isn't updated correctly. What is more, the number returned on the final call to the callback seems to vary depending on the time of day, weather, etc Here is the code that I have used to create the predicate for finding keywords in XMP files…       let xmpFileTypePredicate = NSPredicate(fromMetadataQueryString: "kMDItemKind = \"XMP sidecar*\"cdwt")!       let xmpKeywordPredicate = NSPredicate(fromMetadataQueryString: "kMDItemTextContent = \"<rdf:li>\(keyword)</rdf:li>\"cdw")!       let xmpKeywordsMetadataQueryPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [xmpFileTypePredicate, xmpKeywordPredicate]) Can anyone give me any ideas?
0
0
1.1k
Aug ’22
Replace Threadsafe var with Actor
I have a long established app that uses a threadsafe var to protect an array of URLs from concurrency races, etc… class ThreadsafeVar<T> {   private var value = Optional<T>.none      func callAsFunction() -> T?   {     queue.sync(flags: .barrier) { [unowned self] in value }   }      func set(_ value: T?)   {     queue.async(flags: .barrier) { [unowned self] in self.value = value }   } } What I want to do is substitute an Actor, which I understand will be intrinsically threadsafe. So, I wrote one like this… actor UrlManager {   private var value = [URL]()   func callAsFunction() -> [URL]   {     value   }   func set(_ value: [URL])   {     self.value = value   } } The calling code is in one of four classes, all of which implement a protocol, which contains a read-write var… protocol FolderProtocol { …   var fileURLs: [URL] { get set } } In this particular class, the var is implemented as read-only…   private var urls = ThreadsafeVar<[URL]>()   var fileURLs: [URL]   {     get     {       urls()?.sorted(using: .finder, pathComponent: .fullPath) ?? []     }     set { }   } … the private var being updated from a metadata updating notification handler. Calling the set(_:[URL]) method on the actor poses no problem…       Task { await urls.set(foundURLs) } But, no matter what I try - continuation, try, await, etc, I don't seem to be able to read back the array of URLs from the actor's callAsFunction() method. The fileURLs var is called on the main thread in response to NSCollectionView delegate methods. Other implementing classes don't need the concurrency management as they are fixed once and never changed. Can anyone help me with this one?
1
0
1.3k
Jun ’22
NSMetadataQueryDidFinishGathering not being called enough
I have an app where each item in an NSTableView contains an NSMetadataQuery, to listen for updates to image files that contain the keyword associated with the item. If I write the keywords to, RAW files, everything works as expected and the number label in the row gets updated correctly. However, if I write the keywords to XMP sidecar files, the NSMetadataQueryDidFinishGathering callback isn't called enough times and the count of files affected isn't updated correctly. What is more, the number returned on the final call to the callback seems to vary depending on the time of day, weather, etc Here is the code that I have used to create the predicate for finding keywords in XMP files…       let xmpFileTypePredicate = NSPredicate(fromMetadataQueryString: "kMDItemKind = \"XMP sidecar*\"cdwt")!       let xmpKeywordPredicate = NSPredicate(fromMetadataQueryString: "kMDItemTextContent = \"<rdf:li>\(keyword)</rdf:li>\"cdw")!       let xmpKeywordsMetadataQueryPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [xmpFileTypePredicate, xmpKeywordPredicate]) Can anyone give me any ideas?
Replies
0
Boosts
0
Views
1.1k
Activity
Aug ’22
Replace Threadsafe var with Actor
I have a long established app that uses a threadsafe var to protect an array of URLs from concurrency races, etc… class ThreadsafeVar<T> {   private var value = Optional<T>.none      func callAsFunction() -> T?   {     queue.sync(flags: .barrier) { [unowned self] in value }   }      func set(_ value: T?)   {     queue.async(flags: .barrier) { [unowned self] in self.value = value }   } } What I want to do is substitute an Actor, which I understand will be intrinsically threadsafe. So, I wrote one like this… actor UrlManager {   private var value = [URL]()   func callAsFunction() -> [URL]   {     value   }   func set(_ value: [URL])   {     self.value = value   } } The calling code is in one of four classes, all of which implement a protocol, which contains a read-write var… protocol FolderProtocol { …   var fileURLs: [URL] { get set } } In this particular class, the var is implemented as read-only…   private var urls = ThreadsafeVar<[URL]>()   var fileURLs: [URL]   {     get     {       urls()?.sorted(using: .finder, pathComponent: .fullPath) ?? []     }     set { }   } … the private var being updated from a metadata updating notification handler. Calling the set(_:[URL]) method on the actor poses no problem…       Task { await urls.set(foundURLs) } But, no matter what I try - continuation, try, await, etc, I don't seem to be able to read back the array of URLs from the actor's callAsFunction() method. The fileURLs var is called on the main thread in response to NSCollectionView delegate methods. Other implementing classes don't need the concurrency management as they are fixed once and never changed. Can anyone help me with this one?
Replies
1
Boosts
0
Views
1.3k
Activity
Jun ’22